home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Libraries / objects in c ƒ / Name Sources / NameTable.c < prev   
Encoding:
C/C++ Source or Header  |  1989-03-02  |  4.7 KB  |  242 lines  |  [TEXT/KAHL]

  1. /*    
  2.  *        NameTable abstract class
  3.  *
  4.  *        Sequentially-searched lookup table.  Grows as necessary.
  5.  *        Intended for small lookup tables that use a 32 bit quantity,
  6.  *        not a general object as a key (compared by ==).  This means
  7.  *        that the Name objects can be used (because they are unique)
  8.  *        as can arbitrary long-words (like function addresses, 
  9.  *        #defined symbolic constants, etc.)
  10.  *
  11.  *
  12.  *            Copyright © John Wainwright 1988
  13.  *
  14.  *    SuperClasses :
  15.  *
  16.  *  Instance Vars :
  17.  *                    table
  18.  *                    size
  19.  *    Class Vars :
  20.  *    
  21.  *    Methods :
  22.  *                    new s t            - creates a NameTable of size & type
  23.  *                    get k            - gets the keyed value
  24.  *                    bind k v        - create a binding
  25.  *                    softBind k v     - create a binding only if not there
  26.  *                    push k v        - push v onto the keyed list
  27.  *                    sequence        - setup table sequencing
  28.  *                    next            - next value in table
  29.  *                    nextKey            - next key in table
  30.  *                    dispose            
  31.  *    Class Methods :
  32.  *
  33.  */
  34.  
  35. #include "oic.h"
  36. #include "generics.h"
  37.  
  38. class     NameTable;                    /* the NameTable class                 */
  39.  
  40. typedef struct                        /* table entry                         */
  41. {
  42.     long    key;                    /* key                                */
  43.     object    val;                    /* value                            */
  44. } binding;
  45.  
  46. struct NameTable_i                    /* NameTable instance structure        */
  47. {
  48.     binding    *bindings;                /* array of bindings                */
  49.     int        size;                    /* table size                        */
  50.     int        seqCursor;                /* cursor used for sequencing        */
  51. };
  52. typedef struct NameTable_i NameTable_i;
  53.  
  54. /* -------------------- NameTable Instance methods ------------------- */
  55.  
  56. method object
  57. _bind(self, n, ap)
  58.     object                    self;
  59.     register NameTable_i    *n;
  60.     register struct
  61.     {
  62.         long    key;
  63.         object    value;
  64.     } *ap;
  65. {
  66.     register binding    *b;
  67.     register int         i;
  68.     
  69.     for (b = n->bindings, i = n->size; i--; b++)
  70.         if (b->key == ap->key)
  71.         {
  72.             b->val = ap->value;
  73.             return;
  74.         }
  75.     
  76.     if (n->bindings == NULL)
  77.         n->bindings = talloc(binding);
  78.     else
  79.         n->bindings = (binding *)srealloc(n->bindings,
  80.                         sizeof(binding) * (n->size + 1));
  81.         
  82.     b = &n->bindings[n->size++];
  83.     b->key = ap->key;
  84.     b->val = ap->value;
  85. }
  86.  
  87. method object
  88. _softBind(self, n, ap)
  89.     object                    self;
  90.     register NameTable_i    *n;
  91.     register struct
  92.     {
  93.         long    key;
  94.         object    value;
  95.     } *ap;
  96. {
  97.     register binding    *b;
  98.     register int         i;
  99.     
  100.     for (b = n->bindings, i = n->size; i--; b++)
  101.         if (b->key == ap->key)
  102.             return;
  103.     
  104.     if (n->bindings == NULL)
  105.         n->bindings = talloc(binding);
  106.     else
  107.         n->bindings = (binding *)srealloc(n->bindings,
  108.                         sizeof(binding) * (n->size + 1));
  109.         
  110.     b = &n->bindings[n->size++];
  111.     b->key = ap->key;
  112.     b->val = ap->value;
  113. }
  114.  
  115. method object
  116. _push(self, n, ap)
  117.     object                    self;
  118.     register NameTable_i    *n;
  119.     register struct
  120.     {
  121.         long    key;
  122.         object    value;
  123.     } *ap;
  124. {
  125.     register binding    *b;
  126.     register int         i;
  127.     
  128.     for (b = n->bindings, i = n->size; i--; b++)
  129.         if (b->key == ap->key)
  130.         {
  131.             b->val = push(b->val, ap->value);
  132.             return;
  133.         }
  134.     
  135.     if (n->bindings == NULL)
  136.         n->bindings = talloc(binding);
  137.     else
  138.         n->bindings = (binding *)srealloc(n->bindings,
  139.                         sizeof(binding) * (n->size + 1));
  140.         
  141.     b = &n->bindings[n->size++];
  142.     b->key = ap->key;
  143.     b->val = New(List, ap->value, END);
  144. }
  145.  
  146. method object
  147. _get(self, n, key)
  148.     object                    self;
  149.     register NameTable_i    *n;
  150.     register long             *key;
  151. {
  152.     register binding    *b;
  153.     register int         i;
  154.     
  155.     for (b = n->bindings, i = n->size; i--; b++)
  156.         if (b->key == *key)
  157.             return b->val;
  158.     return NULL;
  159. }
  160.  
  161. method void
  162. _delete(self, n, key)
  163.     object                    self;
  164.     register NameTable_i    *n;
  165.     register long             *key;
  166. {
  167.     register binding    *b;
  168.     register int         i;
  169.     
  170.     for (b = n->bindings, i = n->size; i--; b++)
  171.         if (b->key == *key)
  172.             b->key = NULL;
  173. }
  174.  
  175. method object
  176. _sequence(self, n)                    /* reset sequence start                        */
  177.     object                    self;
  178.     register NameTable_i    *n;
  179. {
  180.     n->seqCursor = 0;
  181.     
  182.     return self;
  183. }
  184.  
  185. method object
  186. _next(self, n)                        /* next value from sequence                    */
  187.     object                    self;
  188.     register NameTable_i    *n;
  189. {
  190.     register binding    *b;
  191.     
  192.     while (n->seqCursor < n->size && (b = &n->bindings[n->seqCursor])->key == NULL)
  193.         n->seqCursor++;
  194.     if (n->seqCursor++ < n->size)
  195.         return b->val;
  196.     else
  197.         return NULL;
  198. }
  199.  
  200. method long
  201. _nextKey(self, n)                    /* next key from sequence                    */
  202.     object                    self;
  203.     register NameTable_i    *n;
  204. {
  205.     register long    k;
  206.     
  207.     while (n->seqCursor < n->size && (k = n->bindings[n->seqCursor].key) == NULL)
  208.         n->seqCursor++;
  209.     if (n->seqCursor++ < n->size)
  210.         return k;
  211.     else
  212.         return NULL;
  213. }
  214.  
  215. method object
  216. _dispose(self, n)
  217.     object                    self;
  218.     register NameTable_i    *n;
  219. {
  220.     free(n->bindings);
  221.     Super(self);
  222. }
  223.  
  224. /* ------------------- Init the NameTable class ---------------------- */
  225.  
  226. InitNameTable()
  227. {
  228.     NameTable = NewClass(sizeof(NameTable_i), 0, "NameTable", END);
  229.     AddMethods(NameTable,
  230.         bindGeneric,         _bind,
  231.         pushGeneric,         _push,
  232.         getGeneric,         _get,
  233.         deleteGeneric,         _delete,
  234.         softBindGeneric,     _softBind,
  235.         nextGeneric,         _next,
  236.         nextKeyGeneric,     _nextKey,
  237.         sequenceGeneric,     _sequence,
  238.         disposeGeneric,     _dispose,
  239.         END);
  240. }
  241.  
  242.